import sys
import pygame
import random
import time
sys.path.append(r'C:\仿魔塔24层')
from 代码 import *    # 初始化文件加入init可省去一长串导入
from control import *
from data import *
from hero import Hero
from monster import MONSTER_DIC as M


def choose_floor(n):
    return floor_ls[n]


class BackGround:
    def __init__(self, h, floor):
        self.h = h
        self.floor = floor
        self.base = choose_floor(self.floor)  # 楼层实例化，只1次
        self.u = False      # 方向指标，用于按下事件可以连续移动
        self.d = False
        self.l = False
        self.r = False
        self.money_shop_3 = False
        self.exp_shop_5 = False
        self.key_shop_5 = False
        self.money_shop_11 = False
        self.exp_shop_13 = False
        self.prop = []      # 存放道具
        self.font = pygame.font.Font(r'C:\Windows\Fonts\simkai.ttf', 15)
        self.green = (0, 255, 127)
        self.clear = False  # 通关指标

    def draw_hero(self):
        self.base.screen.blit(self.base.hero, self.base.pos[self.base.hero_pos[0]][self.base.hero_pos[1]])

    def draw_attribute(self, name, num, font_pos):
        text = self.base.font.render('%s   %.f' % (name, num), 1, self.base.white)
        self.base.screen.blit(text, font_pos)

    def calculator_hp(self, data):
        m_hp, m_attack, m_defend, m_money, m_exp, m_special = M[self.base.dic[data]]
        if self.h.attack <= m_defend:
            return '?'
        elif self.h.defend >= m_attack and not m_special:
            return '0'
        else:
            hero_hp = self.h.HP
            if m_special == '失去25%当前生命':
                hero_hp = int(hero_hp * 0.75)
            elif m_special == '固定掉100血':
                hero_hp = hero_hp - 100
            elif m_special == '固定掉300血':
                hero_hp = hero_hp - 300
            elif m_special == '失去1/3当前生命':
                hero_hp = int(hero_hp * 2 / 3)
            while 1:
                hero_hp -= max(0, (m_attack - self.h.defend))
                m_hp -= (self.h.attack - m_defend)
                m_hp = max(0, m_hp)
                if not m_hp:
                    return str(max(0, self.h.HP - hero_hp))

    def draw_lose_hp(self):
        for data in self.base.dic:
            if self.base.dic[data] in M.keys():
                lose_hp = self.calculator_hp(data)
                text = self.font.render('%s' % lose_hp, 1, self.green)
                x, y = self.base.pos[data[0]][data[1]]
                self.base.screen.blit(text, (x+10, y+30))

    def show_clearframe(self):
        global start
        font = pygame.font.Font(r'C:\Windows\Fonts\simkai.ttf', 50)
        text = font.render('通关！', 1, self.green)
        self.base.screen.blit(text, (580, 150))
        if start:
            print('通关时间=%.2f秒' % (time.time() - t_start))
            start = False

    def move(self):
        if self.u:
            self.base.hero_pos = walk_up(self.base.dic, self.base.hero_pos, self.h, self.base.variable_pos,
                                         self, choose_floor)
        elif self.d:
            self.base.hero_pos = walk_down(self.base.dic, self.base.hero_pos, self.h, self.base.variable_pos,
                                         self, choose_floor)
        elif self.l:
            self.base.hero_pos = walk_left(self.base.dic, self.base.hero_pos, self.h, self.base.variable_pos,
                                         self, choose_floor)
        elif self.r:
            self.base.hero_pos = walk_right(self.base.dic, self.base.hero_pos, self.h, self.base.variable_pos,
                                         self, choose_floor)

    def loop(self, func_ls):
        count = 0
        money_shop_count = 0
        money_shop_count_11 = 0
        exp_shop_count = 0
        exp_shop_count_13 = 0
        hp, atk, dfn, coin, ex, ky, kb, kr = self.h.HP, self.h.attack, self.h.defend, self.h.money, self.h.exp,\
                                             self.h.key_yellow, self.h.key_blue, self.h.key_red
        action_ls = [walk_up, walk_down, walk_left, walk_right]
        while True:  # 主循环
            self.base.screen.fill(self.base.black)  # 填充背景
            a = len(self.base.ls)
            # 画固定方块
            self.base.fixed_brick()
            b = len(self.base.ls)
            if a == b:      # 判断固定场景是否画完
                self.base.variable_brick()
                self.draw_lose_hp()
            self.draw_hero()
            self.draw_attribute('等级', self.h.level, (100, 25))
            self.draw_attribute('生命', self.h.HP, (100, 75))
            self.draw_attribute('攻击', self.h.attack, (100, 125))
            self.draw_attribute('防御', self.h.defend, (100, 175))
            self.draw_attribute('金币', self.h.money, (100, 225))
            self.draw_attribute('经验', self.h.exp, (100, 275))
            self.draw_attribute('黄钥匙', self.h.key_yellow, (100, 325))
            self.draw_attribute('蓝钥匙', self.h.key_blue, (100, 375))
            self.draw_attribute('红钥匙', self.h.key_red, (100, 425))
            self.draw_attribute('楼层', self.floor, (100, 475))
            if self.clear:
                self.show_clearframe()
            # 事件逻辑均为手动部分，自动跑可注释至sleep
            for event in pygame.event.get():
                if event.type is pygame.QUIT:
                    sys.exit()  # 按键响应，按键后退出
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:  # 按上方向键
                        self.u = True
                    if event.key == pygame.K_DOWN:  # 按下方向键
                        self.d = True
                    if event.key == pygame.K_LEFT:  # 按左方向键
                        self.l = True
                    if event.key == pygame.K_RIGHT:  # 按右方向键
                        self.r = True
                elif event.type == pygame.KEYUP:
                    if event.key == pygame.K_UP:  # 按上方向键
                        self.u = False
                    if event.key == pygame.K_DOWN:  # 按下方向键
                        self.d = False
                    if event.key == pygame.K_LEFT:  # 按左方向键
                        self.l = False
                    if event.key == pygame.K_RIGHT:  # 按右方向键
                        self.r = False
            self.move()
            time.sleep(0.08)
            # if count < len(step_ls):
            #     try:        # 按轨迹走
            #         func = action_ls[step_ls[count]]
            #         self.base.hero_pos = func(self.base.dic, self.base.hero_pos, self.h, self.base.variable_pos,
            #                                   self, choose_floor)
            #     except TypeError:   # 楼层跳跃
            #         present_floor = self.floor
            #         self.floor = step_ls[count][0]
            #         self.base = choose_floor(self.floor)
            #         # print('飞到%d楼'%self.floor)
            #         if present_floor > self.floor and self.floor != 1:      # 下楼
            #             self.base.hero_pos = up_down_pos[self.floor][-1]
            #         else:       # 上楼
            #             self.base.hero_pos = up_down_pos[self.floor][0]
            # else:   # 随机前进
            #     try:
            #         left_wall = self.base.dic[self.base.hero_pos[0]-1, self.base.hero_pos[1]] == '墙'    # 判断左边单位，减少无效选择
            #     except KeyError:
            #         left_wall = True
            #     try:
            #         right_wall = self.base.dic[self.base.hero_pos[0]+1, self.base.hero_pos[1]] == '墙'   # 判断右边单位
            #     except KeyError:
            #         right_wall = True
            #     try:
            #         up_wall = self.base.dic[self.base.hero_pos[0], self.base.hero_pos[1]-1] == '墙'      # 判断上边单位
            #     except KeyError:
            #         up_wall = True
            #     try:
            #         down_wall = self.base.dic[self.base.hero_pos[0], self.base.hero_pos[1]+1] == '墙'    # 判断下边单位
            #     except KeyError:
            #         down_wall = True
            #     if up_wall and down_wall and left_wall and not right_wall:       # 上下左
            #         n = 3
            #     elif up_wall and down_wall and right_wall and not left_wall:      # 上下右
            #         n = 2
            #     elif up_wall and left_wall and right_wall and not down_wall:      # 上左右
            #         n = 1
            #     elif down_wall and left_wall and right_wall and not up_wall:    # 下左右
            #         n = 0
            #     elif up_wall and down_wall and not left_wall and not right_wall:      # 上下
            #         n = random.choice([2, 3])
            #     elif up_wall and left_wall and not down_wall and not right_wall:      # 上左
            #         n = random.choice([1, 3])
            #     elif up_wall and right_wall and not down_wall and not left_wall:      # 上右
            #         n = random.choice([1, 2])
            #     elif down_wall and left_wall and not up_wall and not right_wall:      # 下左
            #         n = random.choice([0, 3])
            #     elif down_wall and right_wall and not up_wall and not left_wall:      # 下右
            #         n = random.choice([0, 2])
            #     elif left_wall and right_wall and not up_wall and not down_wall:      # 左右
            #         n = random.choice([0, 1])
            #     elif up_wall and not down_wall and not left_wall and not right_wall:      # 上
            #         n = random.choice([1, 2, 3])
            #     elif down_wall and not up_wall and not left_wall and not right_wall:      # 下
            #         n = random.choice([0, 2, 3])
            #     elif left_wall and not up_wall and not down_wall and not right_wall:      # 左
            #         n = random.choice([0, 1, 3])
            #     elif right_wall and not up_wall and not down_wall and not left_wall:      # 右
            #         n = random.choice([0, 1, 2])
            #     else:
            #         n = random.choice([0, 1, 2, 3])
            #     func = action_ls[n]
            #     func_ls.append(str(n))
            #     self.base.hero_pos = func(self.base.dic, self.base.hero_pos, self.h, self.base.variable_pos,
            #                               self, choose_floor)
            while self.money_shop_3 and self.h.money >= 25 and money_shop_count < 18:      # 金币商店激活后即可随地买
                self.h.money -= 25
                if money_shop_count < len(money_shop_count_ls):
                    flag = money_shop_count_ls[money_shop_count]
                else:
                    flag = random.choice([0, 1])
                    print('随机买')
                    money_shop_count_ls.append(flag)
                if flag:
                    self.h.attack += 4
                else:
                    self.h.defend += 4
                money_shop_count += 1
            # if money_shop_count == 18:
            #     break
            while self.money_shop_11 and self.h.money >= 100 and money_shop_count_11 < 196:      # 金币商店激活后即可随地买
                if 27 < exp_shop_count < 35 or 27 < exp_shop_count_13 < 31 or 52 < exp_shop_count_13 < 70 or 110 < exp_shop_count_13 < 140:
                    break
                if money_shop_count_11 == 18 and not '冰之灵杖' in self.prop:
                    break
                self.h.money -= 100
                if money_shop_count_11 < len(money_shop_count_ls_11):
                    flag = money_shop_count_ls_11[money_shop_count_11]
                else:
                    flag = random.choice([0, 1])
                    print('随机买')
                    money_shop_count_ls_11.append(flag)
                if flag:
                    self.h.attack += 20
                else:
                    self.h.defend += 20
                money_shop_count_11 += 1
            while self.exp_shop_5 and self.h.exp >= 30 and exp_shop_count < 40:      # 经验商店激活后即可随地买
                # 升1级+1000血，攻防各+7
                self.h.exp -= 30
                if exp_shop_count < len(exp_shop_count_ls):
                    flag = exp_shop_count_ls[exp_shop_count]
                else:
                    flag = random.choice([0, 1])
                    print('随机买')
                    exp_shop_count_ls.append(flag)
                if flag:
                    self.h.attack += 5
                else:
                    self.h.defend += 5
                exp_shop_count += 1
            # if exp_shop_count == 12:
                # break
            while self.exp_shop_13 and self.h.exp >= 95 and exp_shop_count_13 < 148:      # 经验商店激活后即可随地买
                self.h.exp -= 95
                if exp_shop_count_13 < len(exp_shop_count_ls_13):
                    flag = exp_shop_count_ls_13[exp_shop_count_13]
                else:
                    flag = random.choice([0, 1])
                    print('随机买')
                    exp_shop_count_ls_13.append(flag)
                if flag:
                    self.h.attack += 17
                else:
                    self.h.defend += 17
                exp_shop_count_13 += 1
            pygame.display.update()     # 刷新
            count += 1
            # if not count % 150:      # 每150次循环判断一次血量，没变就退出
            #     if hp != self.h.HP or atk != self.h.attack or dfn != self.h.defend or coin != self.h.money \
            #             or ex != self.h.exp or ky != self.h.key_yellow or kb != self.h.key_blue or kr != self.h.key_red:
            #         hp, atk, dfn, coin, ex, ky, kb, kr = self.h.HP, self.h.attack, self.h.defend, self.h.money,\
            #                                              self.h.exp, self.h.key_yellow, self.h.key_blue, self.h.key_red
            #     else:
            #         break
        return {'血量': self.h.HP,
                '攻击': self.h.attack,
                '防御': self.h.defend,
                '金币': self.h.money,
                '经验': self.h.exp,
                '金币购买': money_shop_count_ls,
                '经验购买': exp_shop_count_ls}


if __name__ == '__main__':
    ls = []  # 存放每次游戏进程的操作
    def task():
        global floor_ls, money_shop_count_ls, exp_shop_count_ls
        h = Hero()  # 勇士实例化，只1次
        # 楼层实例化列表
        floor_ls = [floor_0.Map(), floor_1.Map(), floor_2.Map(), floor_3.Map(), floor_4.Map(), floor_5.Map(),
                    floor_6.Map(), floor_7.Map(), floor_8.Map(), floor_9.Map(), floor_10.Map(), floor_11.Map(),
                    floor_12.Map(), floor_13.Map(), floor_14.Map(), floor_15.Map(), floor_16.Map(), floor_17.Map(),
                    floor_18.Map(), floor_19.Map(), floor_20.Map(), floor_21.Map(), floor_22.Map(), floor_23_down.Map(),
                    floor_24.Map(), floor_23_left.Map(), floor_23_right.Map()]
        func_ls = []
        hero_info = BackGround(h, 0).loop(func_ls)
        # print(time.time() - t_start, 's')
        # if time.time() - t_start < 25*60:
        #     print('开启隐藏楼层')
    t_start = time.time()
    start = True
    task()
    # 收官运行通关时间=12.86秒
    # with open('../轨迹记录.txt', 'a+', encoding='utf8') as f:
    #     for i in ls:
    #         f.write(str(i[0])+':'+','.join(i[1])+'\n')